package hebClustering.clusteringAlgorithms;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

import hebClustering.Cluster;
import hebClustering.ClusterSet;
import hebClustering.vectorSpace.IVector;
import hebClustering.vectorSpace.distances.IDistance;

/**
 *	Implementation of the clustering algorithm Hierarchical K-means clustering.
 * 
 *	The algorithm operates exactly like the K-means algorithm, except the initialization phase, which in this algorithm
 *	runs K-means P times, on the centroids of the clusters generated runs Hierarchical clustering, 
 *	and then takes the centroids of K clusters generated and uses them as the centroids of the new clusters. 
 * 
 * 	@see <a href="http://dlwww.dl.saga-u.ac.jp/contents/mgzn/ZR00005460/ZR00005460.pdf" target="_blank">Hierarchical K-means clustering</a>, a paper by Kohei Arai and Ali Ridho Barakbah of the Saga University, Japan, 2007.
 */
public class HierarchicalKMeansClustering extends KMeansPPClustering{
	private int P;
	
	public HierarchicalKMeansClustering(int K,int I, int P, IDistance distance) {
		super(K, I, distance);
		this.P = P;
	}
	
	protected void initializeMeans(Collection<IVector> dataSet,ClusterSet clusterSet) {
		
		Set<IVector> newDataSet = new HashSet<IVector>();
		KMeansPPClustering kClustering = new KMeansPPClustering(K, I, distance);
		
		for (int i = 0; i < P; i++){
			ClusterSet currentClusterSet = kClustering.cluster(dataSet);
			for (Cluster c : currentClusterSet){
				newDataSet.add(c.findCentroid());
			}
		}
		
		IClusteringAlgorithm hClustering = new HierarchicalClustering(K, distance);
		ClusterSet meansClusters = hClustering.cluster(newDataSet);
		
		for (Cluster c : meansClusters){
			Cluster newCluster = new Cluster(c.findCentroid());
			clusterSet.add(newCluster);
		}
	}

}
